﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Windows.Forms;
using Game.Foundation;
using Game.Foundation.Client;
using Bruce.Net;

namespace Game.Client
{
    public partial class RoomControl : UserControl, IParentClient
    {
        private GameConnection _gameConnection;
        //private ChessGameForm _gameForm;
        private Process _childProcess;
        private Dictionary<int, GameGroup> _groupDict;
        private int _currentAreaId;
        private int _currentRoomId;
        private int _currentGroupId;
        private string _userName;
        private string _gameName;
        private string _relativePath;

        public string Key
        {
            get
            {
                return string.Format("{0}|{1}|{2}", this._gameName, this._currentAreaId, this._currentRoomId);
            }
        }


        public RoomControl(AsyncWorkSocket socket, string userName, string gameName, string relativePath, int areaId, int roomId)
        {
            InitializeComponent();

            this._userName = userName;
            this._gameName = gameName;
            this._relativePath = relativePath;
            this._currentAreaId = areaId;
            this._currentRoomId = roomId;

            this._gameConnection = GameConnection.CreateConnection(socket, this._userName, this._currentAreaId, this._currentRoomId);
            this._gameConnection.ReceivedLoginResponse += new EventHandler<BasicEventArgs>(_client_ReceivedLoginResponse);
            this._gameConnection.ReceivedChatInfo += new EventHandler<ChatEventArgs>(_client_ReceivedChatInfo);
            this._gameConnection.ReceivedGameGroupList += new EventHandler<GameGroupCollectionEventArgs>(_client_ReceivedGameGroupList);
            this._gameConnection.GameGroupChanged += new EventHandler<GameGroupChangedEventArgs>(_client_GameGroupChanged);
            this._gameConnection.ReceicedNewGameNotify += new EventHandler<PacketEventArgs>(_client_ReceicedNewGameNotify);

            this._gameConnection.CurrentHandExchanged += new EventHandler<Game.Foundation.ExchangeHandEventArgs>(_client_CurrentHandExchanged);
            this._gameConnection.ChessmanLocationMoved += new EventHandler<PacketEventArgs>(_client_ChessmanLocationMoved);
            this._gameConnection.GameCompleted += new EventHandler<PacketEventArgs>(_client_GameCompleted);

            this.ParentChanged += new EventHandler(RoomControl_ParentChanged);
            RemoteServer.GetSingletomServer(Program.Port).RegisterParent(this.Key, this);
        }

        void RoomControl_ParentChanged(object sender, EventArgs e)
        {
            this.FindForm().FormClosing += new FormClosingEventHandler(RoomControl_FormClosing);
        }

        void RoomControl_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.ChildClient != null)
            {
                RemoteServer.GetSingletomServer(Program.Port).UnRegisterChild(this.Key);
                this._childProcess.CloseMainWindow();
            }
        }

        private void btnSendChatMsg_Click(object sender, EventArgs e)
        {
            this.SendChatMessage(txtInput.Text);
        }

        private void treeGroupList_DoubleClick(object sender, EventArgs e)
        {
            if (treeGroupList.SelectedNode == null || treeGroupList.SelectedNode.Text != "可进入") return;

            string tag = treeGroupList.SelectedNode.Tag.ToString();
            if (string.IsNullOrEmpty(tag)) return;

            string[] paramArray = tag.Split('|');
            this._currentGroupId = int.Parse(paramArray[0]);
            //if (this.ChildClient != null)
            //{
            //    //RemoteServer.GetSingletomServer(Program.Port).UnRegisterChild(this.Key);
            //    //this._childProcess.CloseMainWindow();                
            //}

            this._gameConnection.JoinGameGroup(this._currentAreaId, this._currentRoomId, this._currentGroupId, byte.Parse(paramArray[1]));
        }

        void _client_ReceivedLoginResponse(object sender, BasicEventArgs e)
        {
            this.DoActionCrossThreads(() =>
            {
                switch (e.ReturnCode)
                {
                    case 1:
                        MessageBox.Show("角色名已被注册，请重新输入");
                        break;
                }
            });
        }

        void _client_ReceicedNewGameNotify(object sender, PacketEventArgs e)
        {
            int deskId = (e.Packet as Packet).ReadInt32();
            this.DoActionCrossThreads(() =>
            {
                if (deskId == this._currentGroupId)
                {
                    this.ChildClient.Initialize(e.Packet.ToBinary());
                }
            });
        }

        void _client_GameGroupChanged(object sender, GameGroupChangedEventArgs e)
        {
            var role = this._groupDict[e.GroupID].RoleList.SingleOrDefault(r => r.SeatIndex == e.SeatIndex);

            if (role == null && e.ChangeType == GameStatus.Unready)
            {
                role = new Role
                {
                    SeatIndex = e.SeatIndex,
                    Status = GameStatus.Unready,
                    UserName = e.UserName,
                };
                this._groupDict[e.GroupID].RoleList.Add(role);

                if (e.UserName == this._userName)
                {
                    if (this.ChildClient == null)
                    {
                        this._childProcess = Process.Start(this._relativePath, string.Format("{0} {1} {2} {3}", this._userName, this.Key, e.SeatIndex, Program.Port));
                    }
                    else
                    {
                        this.ChildClient.ExchangeDesk(e.GroupID, e.SeatIndex);
                    }
                }
            }

            if (this.ChildClient != null && this._userName == e.UserName)
            {
                this.ChildClient.Status = e.ChangeType;
            }
            role.Status = e.ChangeType;

            if (e.ChangeType == GameStatus.Absent)
            {
                this._groupDict[e.GroupID].RoleList.Remove(role);
            }

            this.DoActionCrossThreads(() =>
            {
                this.RefreshGroupTree();
            });
        }

        void _client_ReceivedGameGroupList(object sender, GameGroupCollectionEventArgs e)
        {
            this._groupDict = e.GroupList.ToDictionary(g => g.ID);
            this.DoActionCrossThreads(() =>
            {
                RefreshGroupTree();
            });
        }

        void _client_ReceivedChatInfo(object sender, ChatEventArgs e)
        {
            this.DoActionCrossThreads(() =>
            {
                txtMessageHistory.Text += e.Content;
                txtMessageHistory.Text += Environment.NewLine;
                txtMessageHistory.SelectionStart = txtMessageHistory.Text.Length;
                txtMessageHistory.ScrollToCaret();
            });
        }

        void _client_CurrentHandExchanged(object sender, Game.Foundation.ExchangeHandEventArgs e)
        {
            this.DoActionCrossThreads(() =>
            {
                this.ChildClient.ExchangeHand(e.CurrentSeat);
            });
        }

        void _client_ChessmanLocationMoved(object sender, PacketEventArgs e)
        {
            this.DoActionCrossThreads(() =>
            {
                this.ChildClient.GameSynchronize(e.Packet.ToBinary());
            });
        }

        void _client_GameCompleted(object sender, PacketEventArgs e)
        {
            this.ChildClient.GameOver(e.Packet.ToBinary());
        }

        private void RefreshGroupTree()
        {
            treeGroupList.Nodes.Clear();
            foreach (int key in this._groupDict.Keys)
            {
                treeGroupList.Nodes.Add(key.ToString(), key.ToString());
                TreeNode group = treeGroupList.Nodes[key.ToString()];

                for (int i = 0; i < 2; i++)
                {
                    TreeNode emptySeat = new TreeNode("可进入");
                    emptySeat.Tag = string.Format("{0}|{1}", key, i);
                    group.Nodes.Add(emptySeat);
                }
                foreach (var player in this._groupDict[key].RoleList)
                {
                    group.Nodes[player.SeatIndex].Text = player.UserName;
                    switch (player.Status)
                    {
                        case GameStatus.Gaming:
                            group.Nodes[player.SeatIndex].ForeColor = Color.Red;
                            break;
                        case GameStatus.Ready:
                            group.Nodes[player.SeatIndex].ForeColor = Color.Blue;
                            break;
                        case GameStatus.Unready:
                            group.Nodes[player.SeatIndex].ForeColor = Color.Black;
                            break;
                    }
                }
            }

            treeGroupList.ExpandAll();
        }

        #region IParentClient 成员

        public IChildClient ChildClient
        {
            get;
            set;
        }

        [OneWay]
        public void ChangeReadyStatus(GameStatus target)
        {
            this._gameConnection.ChangeReadyStatus(target);
        }

        [OneWay]
        public void DoGameOperation(byte[] buffer)
        {
            Packet cmdPacket = (Packet)PacketLoader.Default.Parse(buffer);
            this._gameConnection.MoveChessman(cmdPacket);
        }

        [OneWay]
        public void SendChatMessage(string msg)
        {
            this._gameConnection.SendChatMessage(msg);
        }

        #endregion
    }
}
